/**************************************************************************************
 * Copyright (C) 2011 Lantana Software Technologies, Inc. All rights reserved.        *
 *																					  *	
 * * -------------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the GPL license       *
 * a copy of which has been included with this distribution in the license.txt file.  *
 **************************************************************************************/

package com.lantanasoft.dataprocessing.smoothing;

import java.util.ArrayList;

import org.apache.log4j.Logger;

import com.lantanasoft.dataprocessing.DPException;

public class AverageSmoothing implements Smoothing {

	private final Logger logger = Logger.getLogger(AverageSmoothing.class);

	/***
	 * This implements Average Smoothing as a special case of generalized Linear
	 * Filters.
	 ***/

	public double[] doSmoothing(double[] data, int nonRecursionLen,
			int recursionLen) throws DPException {

		logger.info("Average Smoothing called with Non Rescursion: "
				+ nonRecursionLen + " and Recursion : " + recursionLen);
		
		ArrayList<Double> ck = new ArrayList<Double>();
		ArrayList<Double> dk = new ArrayList<Double>();

		int startIndex = Math.max(nonRecursionLen, recursionLen);

		/* Find and Set the Coefficients */
		
		logger.info("Finding the Coeffcients for Average Smoothing");
		double avNonRecursnCoeff = 1.0 / ((nonRecursionLen + 1));
		double avRecursnCoeff = 1.0 / (recursionLen);
		for (int i = 0; i <= nonRecursionLen; i++) {
			ck.add(i, new Double(avNonRecursnCoeff));
		}
		for (int i = 0; i <= recursionLen; i++) {
			dk.add(i, new Double(avRecursnCoeff));
		}
		double tempData = 0.0;
		logger.info(" Data length : " + data.length);
		double[] resultData = new double[data.length];
		for (int t = 0; t < data.length; t++)
			resultData[t] = data[t];
		/*
		 * Main Loop that implements the Linear filter smoothing Eq 13.5.1
		 * Numerical Recipes. The first Max(RecursnLen, NonRecursionLen) is
		 * ignored.
		 */
		for (int k = startIndex; k < data.length; k++) {

			for (int l = (k - nonRecursionLen); l <= k; l++) {
				tempData = tempData
						+ (((Double) ck.get(l - (k - nonRecursionLen)))
								.doubleValue()) * (data[l]);

			}

			for (int l = (k - recursionLen); l < k; l++) {

				tempData = tempData
						+ ((Double) dk.get(l - (k - recursionLen)))
								.doubleValue() * (resultData[l]);
			}

			resultData[k] = tempData;
			tempData = 0;
		}
		return resultData;
	}
}
